from django.conf import settings
import hashlib
import hmac
import time


# 生成32位的随机字符串
def get_nonce_str():
    import uuid

    return str(uuid.uuid4()).replace('-', '')


class WeChatPay(object):
    def __init__(self, order_id, body, total_fee, nonce_str, openid, spbill_create_ip='8.8.8.8'):
        """
        :param order_id: 订单编号，32字符以内
        :param body: 订单标题，订单信息，如：腾讯充值中心-QQ会员充值
        :param total_fee: 订单金额，单位为分
        :param nonce_str: 32位随机字符串
        :param openid: 用户的openid(唯一标识)
        :param spbill_create_ip: 客户端请求的IP地址
        appid '微信appid'
        appid = settings.WECHAT_APP_ID
        AppSecret '微信AppSecret'
        AppSecret = settings.WECHAT_APP_KEY
        mcg_id '微信商户id'
        mch_id = settings.WECHAT_PAY_ID
        api_key '微信支付密钥'
        api_key = settings.WECHAT_PAY_API_KEY
        spbill_create_ip = '8.8.8.8'
        """
        self.api_key = settings.WECHAT_PAY_API_KEY
        self.params = {
            'appid': settings.WECHAT_APP_ID,
            'mch_id': settings.WECHAT_PAY_ID,
            'nonce_str': get_nonce_str(),
            'openid': openid,
            'body': body,
            'out_trade_no': order_id,
            'total_fee': total_fee,
            'spbill_create_ip': spbill_create_ip,
            'notify_url': 'https://www.baidu.com',  # 支付回调地址
            'trade_type': 'JSAPI',  # 小程序接口为JSAPI
        }

        self.WxPay_request_url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'  # 小程序发起支付链接
        self.error = None

    def key_value_url(self, value):
        # 将键值对转换成key1=value1&key2=value2
        string_sign = ''
        for k in sorted(value.keys()):  # sorted : ASCII字典序排序
            string_sign += "{0}={1}&".format(k, value[k])
        print('键值对：', string_sign)
        return string_sign

    def get_sign(self, params):
        """
        生成sign签名
        :param params: 传入参数
        :return:
        """
        stringA = self.key_value_url(params)
        stringSignTemp = stringA + 'key=' + self.api_key  # APIKEY,API密钥，需要在商户后台设置
        print('最终键值对:', stringSignTemp)
        sign = hashlib.md5(stringSignTemp.encode('utf-8')).hexdigest().upper()
        print("最终生成的签名：", sign)
        params['sign'] = sign

    def get_req_xml(self):
        """
        拼接xml
        :return:
        """
        self.get_sign(self.params)
        xml = "<xml>"
        for k in sorted(self.params.keys()):
            xml += '<{0}>{1}</{0}>'.format(k, self.params[k])
        xml += "</xml>"
        print("得到的XML：", xml)
        return xml.encode('utf-8')

    def get_prepay_id(self):
        """
        请求获取prepay_id
        :return:
        """
        import requests
        from xml.etree import ElementTree as et
        xml = self.get_req_xml()
        unifiedorderXML = requests.post(self.WxPay_request_url, data=xml)
        unifiedorderXML.encoding = 'utf-8'
        unifiedorderXML = unifiedorderXML.text
        print("统一下单接口返回的接口数据", unifiedorderXML)
        root = et.fromstring(unifiedorderXML)
        if root.find("result_code").text != 'SUCCESS':
            self.error = u"连接微信出错啦"
            print(self.error)
        prepay_id = root.find("prepay_id").text
        print('i am prepay_id:',prepay_id)
        self.params['prepay_id'] = prepay_id
        self.params['package'] = 'prepay_id=%s' % prepay_id  # 微信小程序JSAPI支付场景
        self.params['timestamp'] = str(int(time.time()))
        self.params['signType'] = 'MD5'

    def re_finall(self):
        """
        得到prepay_id 后再次签名，返回给终端参数
        :return:
        """
        self.get_prepay_id()
        if self.error:
            print("有错误发生：", self.error)
            return

        sign_again_params = {
            'appId': self.params['appid'],
            'timeStamp': self.params['timestamp'],
            'nonceStr': self.params['nonce_str'],
            'package': self.params['package'],
            'signType': self.params['signType'],
        }

        self.get_sign(sign_again_params)
        self.params['sign'] = sign_again_params['sign']

        # 移除其他不需要返回参数
        print('最后一步：', self.params)
        parms_keys = []
        for i in self.params.keys():
            parms_keys.append(i)
        for i in parms_keys:
            if i not in ['appid', 'mch_id', 'nonce_str', 'timestamp', 'sign', 'package', 'signType']:
                self.params.pop(i)
        print('传给前端的parms', self.params)
        return self.params